import * as THREE from 'three';
import { Vec3 } from '@/core/types';
import { BlockType } from '@/blocks/types';
import { TextureManager } from '@/blocks/TextureManager';

export interface DroppedItem {
  id: string;
  type: BlockType;
  count: number;
  position: Vec3;
  velocity: Vec3;
  mesh: THREE.Mesh;
  createdAt: number;
  collected: boolean;
}

export class ItemDropManager {
  private droppedItems: Map<string, DroppedItem> = new Map();
  private scene: THREE.Scene;
  private nextId = 0;

  constructor(scene: THREE.Scene) {
    this.scene = scene;
  }

  public dropItem(type: BlockType, count: number, position: Vec3): void {
    const id = `item_${this.nextId++}`;
    
    // 创建掉落物的3D模型
    const mesh = this.createItemMesh(type);
    mesh.position.set(position.x + 0.5, position.y + 0.5, position.z + 0.5);
    
    // 添加随机的初始速度
    const velocity: Vec3 = {
      x: (Math.random() - 0.5) * 2,
      y: Math.random() * 3 + 1,
      z: (Math.random() - 0.5) * 2
    };

    const droppedItem: DroppedItem = {
      id,
      type,
      count,
      position: { ...position },
      velocity,
      mesh,
      createdAt: Date.now(),
      collected: false
    };

    this.droppedItems.set(id, droppedItem);
    this.scene.add(mesh);
  }

  private createItemMesh(type: BlockType): THREE.Mesh {
    // 创建一个小的立方体来表示掉落的物品
    const geometry = new THREE.BoxGeometry(0.3, 0.3, 0.3);
    
    // 获取对应方块的材质
    const textureManager = TextureManager.getInstance();
    const material = textureManager.createBlockMaterial(this.getItemTexture(type));
    
    const mesh = new THREE.Mesh(geometry, material);
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    
    return mesh;
  }

  private getItemTexture(type: BlockType): string {
    // 为不同的方块类型返回合适的纹理名称
    const textureMap: Partial<Record<BlockType, string>> = {
      [BlockType.GRASS]: 'grass_top',
      [BlockType.DIRT]: 'dirt',
      [BlockType.STONE]: 'stone',
      [BlockType.LOG]: 'log_side',
      [BlockType.PLANKS]: 'planks',
      [BlockType.COAL_ORE]: 'coal_ore',
      [BlockType.FURNACE]: 'furnace_front',
      [BlockType.TORCH]: 'torch',
      [BlockType.CRAFTING_TABLE]: 'crafting_table_top',
      [BlockType.SAND]: 'sand',
      [BlockType.SANDSTONE]: 'sandstone_side',
      [BlockType.GLASS]: 'glass',
      [BlockType.IRON_ORE]: 'iron_ore',
      [BlockType.GOLD_ORE]: 'gold_ore',
      [BlockType.DIAMOND_ORE]: 'diamond_ore',
      [BlockType.WATER]: 'water',
      [BlockType.OBSIDIAN]: 'obsidian',
      [BlockType.REDSTONE_WIRE]: 'redstone_wire',
      [BlockType.REDSTONE_TORCH]: 'redstone_torch',
      [BlockType.COBBLESTONE]: 'cobblestone',
      [BlockType.GRAVEL]: 'gravel',
      [BlockType.CLAY]: 'clay',
      [BlockType.BRICK]: 'brick',
      [BlockType.SNOW]: 'snow',
      // 新增物品类型
      [BlockType.COAL_ITEM]: 'coal_item',
      [BlockType.LEAVES]: 'leaves',
      [BlockType.BIRCH_LOG]: 'birch_log_side',
      [BlockType.SPRUCE_LOG]: 'spruce_log_side',
      [BlockType.BIRCH_LEAVES]: 'birch_leaves',
      [BlockType.SPRUCE_LEAVES]: 'spruce_leaves',
      [BlockType.WET_LEAVES]: 'wet_leaves',
      [BlockType.SAPLING]: 'sapling',
      [BlockType.ENDER_PEARL]: 'ender_pearl',
      [BlockType.IRON_INGOT]: 'iron_ingot',
      [BlockType.GOLD_INGOT]: 'gold_ingot',
      [BlockType.DIAMOND]: 'diamond',
      [BlockType.RAW_IRON]: 'raw_iron',
      [BlockType.RAW_GOLD]: 'raw_gold',
      // 生物掉落物品
      [BlockType.LEATHER]: 'leather',
      [BlockType.RAW_BEEF]: 'raw_beef',
      [BlockType.RAW_PORKCHOP]: 'raw_porkchop',
      [BlockType.WOOL]: 'wool',
      [BlockType.MUTTON]: 'mutton',
      [BlockType.ROTTEN_FLESH]: 'rotten_flesh',
      [BlockType.BONE]: 'bone',
      [BlockType.ARROW]: 'arrow',
      [BlockType.BOW]: 'bow'
    };

    return textureMap[type] || 'stone';
  }

  public update(deltaTime: number, playerPosition: Vec3, onItemCollected?: (item: DroppedItem) => boolean): void {
    const gravity = -9.8;
    const collectDistance = 1.5;
    const magnetDistance = 3.0; // 磁吸距离
    const itemLifetime = 300000; // 5分钟后消失
    const currentTime = Date.now();

    for (const [id, item] of this.droppedItems) {
      if (item.collected) continue;

      // 检查物品是否过期
      if (currentTime - item.createdAt > itemLifetime) {
        this.removeItem(id);
        continue;
      }

      // 应用重力
      item.velocity.y += gravity * deltaTime;

      // 计算到玩家的距离
      const distance = Math.sqrt(
        Math.pow(item.position.x - playerPosition.x, 2) +
        Math.pow(item.position.y - playerPosition.y, 2) +
        Math.pow(item.position.z - playerPosition.z, 2)
      );

      // 磁吸效果 - 当玩家靠近时，物品会被吸引
      if (distance <= magnetDistance && distance > collectDistance) {
        const attractionForce = 5.0 * (1 - distance / magnetDistance);
        const directionX = (playerPosition.x - item.position.x) / distance;
        const directionY = (playerPosition.y - item.position.y) / distance;
        const directionZ = (playerPosition.z - item.position.z) / distance;
        
        item.velocity.x += directionX * attractionForce * deltaTime;
        item.velocity.y += directionY * attractionForce * deltaTime;
        item.velocity.z += directionZ * attractionForce * deltaTime;
      }

      // 更新位置
      item.position.x += item.velocity.x * deltaTime;
      item.position.y += item.velocity.y * deltaTime;
      item.position.z += item.velocity.z * deltaTime;

      // 简单的地面碰撞检测
      if (item.position.y <= 0) {
        item.position.y = 0;
        item.velocity.y = 0;
        item.velocity.x *= 0.8; // 摩擦力
        item.velocity.z *= 0.8;
      }

      // 更新网格位置
      item.mesh.position.set(
        item.position.x + 0.5,
        item.position.y + 0.15,
        item.position.z + 0.5
      );

      // 添加旋转动画
      item.mesh.rotation.y += deltaTime * 2;

      // 检查是否可以被玩家收集
      if (distance <= collectDistance) {
        // 尝试自动收集物品
        if (onItemCollected && onItemCollected(item)) {
          // 创建收集效果
          this.createCollectionEffect(item);
          // 移除物品
          this.removeItem(id);
          console.log(`Collected ${item.count}x ${BlockType[item.type]}`);
        } else {
          // 标记为可收集
          item.collected = true;
        }
      }
    }
  }

  public getCollectableItems(playerPosition: Vec3, collectDistance: number = 1.5): DroppedItem[] {
    const collectableItems: DroppedItem[] = [];

    for (const item of this.droppedItems.values()) {
      if (item.collected) continue;

      const distance = Math.sqrt(
        Math.pow(item.position.x - playerPosition.x, 2) +
        Math.pow(item.position.y - playerPosition.y, 2) +
        Math.pow(item.position.z - playerPosition.z, 2)
      );

      if (distance <= collectDistance) {
        collectableItems.push(item);
      }
    }

    return collectableItems;
  }

  public collectItem(itemId: string): DroppedItem | null {
    const item = this.droppedItems.get(itemId);
    if (item && item.collected) {
      this.removeItem(itemId);
      return item;
    }
    return null;
  }

  private removeItem(itemId: string): void {
    const item = this.droppedItems.get(itemId);
    if (item) {
      this.scene.remove(item.mesh);
      item.mesh.geometry.dispose();
      if (Array.isArray(item.mesh.material)) {
        item.mesh.material.forEach(mat => mat.dispose());
      } else {
        item.mesh.material.dispose();
      }
      this.droppedItems.delete(itemId);
    }
  }

  public clear(): void {
    for (const itemId of this.droppedItems.keys()) {
      this.removeItem(itemId);
    }
  }

  public getItemCount(): number {
    return this.droppedItems.size;
  }

  /**
   * 创建物品收集效果
   */
  private createCollectionEffect(item: DroppedItem): void {
    if (!item.mesh.parent) return;

    // 创建收集粒子效果
    const particleCount = 10;
    for (let i = 0; i < particleCount; i++) {
      const particle = new THREE.Mesh(
        new THREE.SphereGeometry(0.02),
        new THREE.MeshBasicMaterial({
          color: 0x00FF00,
          transparent: true,
          opacity: 0.8
        })
      );
      
      particle.position.copy(item.mesh.position);
      particle.position.add(new THREE.Vector3(
        (Math.random() - 0.5) * 0.5,
        (Math.random() - 0.5) * 0.5,
        (Math.random() - 0.5) * 0.5
      ));
      
      item.mesh.parent.add(particle);
      
      // 粒子动画
      const startTime = Date.now();
      const animate = () => {
        const elapsed = Date.now() - startTime;
        if (elapsed > 500) {
          if (particle.parent) {
            particle.parent.remove(particle);
          }
          particle.geometry.dispose();
          (particle.material as THREE.Material).dispose();
          return;
        }
        
        particle.position.y += 0.02;
        (particle.material as THREE.MeshBasicMaterial).opacity = 0.8 * (1 - elapsed / 500);
        requestAnimationFrame(animate);
      };
      animate();
    }
  }
}